package com.faithbj.device.model.entity;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.ForeignKey;
import org.hibernate.validator.constraints.Email;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

@Entity
@Table(name="members")
public class Members extends BaseEntity implements UserDetails {
	private static final long serialVersionUID = -5222673112266471971L;
	
	
	public static final String LOGIN_MEMBER_ID_SESSION_NAME = "loginMemberId";// 保存登录会员ID的Session名称
	public static final String LOGIN_MEMBER_USERNAME_COOKIE_NAME = "loginMemberUsername";// 保存登录会员用户名的Cookie名称
	public static final String LOGIN_REDIRECTION_URL_SESSION_NAME = "redirectUrl";// 保存登录来源URL的Session名称
	public static final String PASSWORD_RECOVER_KEY_SEPARATOR = "_";// 密码找回Key分隔符
	public static final int PASSWORD_RECOVER_KEY_PERIOD = 10080;// 密码找回Key有效时间（单位：分钟）
	
	@NotNull(message = "user.username.null")  
    @Pattern(regexp = "[a-zA-Z0-9_]{5,18}", message = "用户名不合法！")
	private String username;// 用户名
	
	/**
	 * 真实姓名
	 */
	private String realName;

	private String password;// 密码
	@Email
	private String email;// E-mail

	private String telephone;// 电话或手机号

	private String safeQuestion;// 密码保护问题

	private String safeAnswer;// 密码保护问题答案

	private Boolean enabled=true;// 账号是否启用

	private Boolean accountNonLocked=true;// 账号是否锁定

	private Integer loginFailureCount=0;// 连续登录失败的次数

	private Boolean credentialsNonExpired=true;// 凭证是否过期
	
	private Set<Roles> roles;// 管理角色
	
	private Collection<? extends GrantedAuthority> authorities;// 授权信息
	
	private Date lockedDate;// 账号锁定日期

	private String registerIp;// 注册IP

	private String loginIp;// 最后登录IP

	private Date loginDate;// 最后登录日期

	private String passwordRecoverKey;// 密码找回Key

	private Set<Reservation> reservations;// 预订列表
	
	@Column(name="real_name")
	public String getRealName() {
		return realName;
	}	  
	@Column(updatable = false, nullable = false, unique = true)
	public String getUsername() {
		return username;
	}
	@Column(nullable = false)
	public String getPassword() {
		return password;
	}
	@Column(nullable = false)	
	public String getEmail() {
		return email;
	}
	@Column(nullable = false)
	public String getTelephone() {
		return telephone;
	}
	@Column(name="safe_question",nullable = true)
	public String getSafeQuestion() {
		return safeQuestion;
	}
	@Column(name="safe_answer",nullable = true)
	public String getSafeAnswer() {
		return safeAnswer;
	}
	@Column(nullable = false)	
	public Boolean getEnabled() {
		return enabled;
	}
	@Column(name="account_non_locked")
	public Boolean getAccountNonLocked() {
		return accountNonLocked;
	}
	@Column(name="login_failure_count",nullable = false)
	public Integer getLoginFailureCount() {
		return loginFailureCount;
	}
	@Column(name="credentials_non_expired",nullable = false)	
	public Boolean getCredentialsNonExpired() {
		return credentialsNonExpired;
	}
	
	@ManyToMany(fetch=FetchType.LAZY)
    @JoinTable(name="members_roles")
	@JoinColumn(name="roles")
	@ForeignKey(name="fk_member_role_set")
	public Set<Roles> getRoles() {
		return roles;
	}
	
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "member")
	public Set<Reservation> getReservations() {
		return reservations;
	}
	
	@Column(name="locked_date")
	public Date getLockedDate() {
		return lockedDate;
	}
	@Column(name="register_ip",nullable = false, updatable = false)
	public String getRegisterIp() {
		return registerIp;
	}	
	@Column(name="login_ip",nullable = false)
	public String getLoginIp() {
		return loginIp;
	}
	@Column(name="login_date",nullable = false)
	public Date getLoginDate() {
		return loginDate;
	}
	@Column(name="password_recover_key",nullable = true)
	public String getPasswordRecoverKey() {
		return passwordRecoverKey;
	}	

	@Transient
	public boolean isEnabled() {
		return enabled;
	}		
	@Transient
	public Collection<SimpleGrantedAuthority> getAuthorities() {
		List<SimpleGrantedAuthority> list=new ArrayList<SimpleGrantedAuthority>();
		for (Roles role : roles)
			list.add(new SimpleGrantedAuthority(role.getValue()));
	    return list;
	}
	/**
	 * 账户永远不会过期
	 */
	@Transient
	@Override
	public boolean isAccountNonExpired() {
		return true;
	}
	@Transient
	@Override
	public boolean isAccountNonLocked() {
		return accountNonLocked;
	}
	@Transient
	@Override
	public boolean isCredentialsNonExpired() {
		return credentialsNonExpired;
	}	
	
	
	public void setEnabled(Boolean enabled) {
		this.enabled = enabled;
	}
	public void setAccountNonLocked(Boolean accountNonLocked) {
		this.accountNonLocked = accountNonLocked;
	}	
	public void setCredentialsNonExpired(Boolean credentialsNonExpired) {
		this.credentialsNonExpired = credentialsNonExpired;
	}		
	public void setRoles(Set<Roles> roles) {
		this.roles = roles;
	}	
	public void setLockedDate(Date lockedDate) {
		this.lockedDate = lockedDate;
	}
	public void setRegisterIp(String registerIp) {
		this.registerIp = registerIp;
	}	
	public void setLoginIp(String loginIp) {
		this.loginIp = loginIp;
	}
	public void setLoginDate(Date loginDate) {
		this.loginDate = loginDate;
	}
	public void setPasswordRecoverKey(String passwordRecoverKey) {
		this.passwordRecoverKey = passwordRecoverKey;
	}	
	public void setAuthorities(Collection<SimpleGrantedAuthority> authorities) {
		this.authorities = authorities;
	}	
	
	
	public void setUsername(String username) {
		this.username = username;
	}
	public void setPassword(String password) {
		this.password = password;
	}

	public void setEmail(String email) {
		this.email = email;
	}
	public void setTelephone(String telephone) {
		this.telephone = telephone;
	}
	public void setSafeQuestion(String safeQuestion) {
		this.safeQuestion = safeQuestion;
	}
	public void setSafeAnswer(String safeAnswer) {
		this.safeAnswer = safeAnswer;
	}	
	public void setLoginFailureCount(Integer loginFailureCount) {
		this.loginFailureCount = loginFailureCount;
	}
	
/*	@Transient
	public void onSave()
	{
		    if (this.enabled == null)
		      this.enabled = Boolean.valueOf(false);
		    if (this.accountNonLocked == null)
		      this.accountNonLocked = Boolean.valueOf(false);
		    if ((this.loginFailureCount == null) || (this.loginFailureCount.intValue() < 0))
		      this.loginFailureCount = Integer.valueOf(0);
	}

	@Transient
	public void onUpdate()
	{
		    if (this.enabled == null)
		      this.enabled = Boolean.valueOf(false);
		    if (this.accountNonLocked == null)
		      this.accountNonLocked = Boolean.valueOf(false);
		    if ((this.loginFailureCount == null) || (this.loginFailureCount.intValue() < 0))
		      this.loginFailureCount = Integer.valueOf(0);
	}*/

	public void setReservations(Set<Reservation> reservations) {
		this.reservations = reservations;
	}

	public void setRealName(String realName) {
		this.realName = realName;
	}
	public void handleBlankProperties() {
		if(StringUtils.isBlank(this.getUsername()))
			this.setUsername(null);
		
		if(StringUtils.isBlank(this.getRealName()))
			this.setRealName(null);
		
		if(StringUtils.isBlank(this.getTelephone()))
			this.setTelephone(null);
		
	}
	
	
	
	
}
